/*
* Headmanager.cpp
*
* Created by Joey van der Bie and Vincent Vijn
* www.vanderBie.net & Vincent.Vijn.me
* With code from Theo Watson, Jesus Gollonet and Diego Diaz
*
* 15-04-2010
* Media Technology - University Leiden
*/
#include "headmanager.h"


static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade = 0;

void headmanager::allocate(int width, int height){
    camW = width;
    camH = height;
	scale = 2.0;

	gray = cvCreateImage( cvSize(width,height), 8, 1 );
	small_img = cvCreateImage( cvSize( cvRound (width/scale),cvRound (height/scale)),8, 1 );

	int optlen = strlen("--cascade=");
	//cascade_name = "C:\\Program Files\\OpenCV\\data\\haarcascades\\haarcascade_frontalface_alt.xml";
    cascade_name = "C:\\OpenCV2.0\\data\\haarcascades\\haarcascade_frontalface_alt2.xml";
    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

    if( !cascade )
    {
        fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
        fprintf( stderr,
        "Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );
    }
    storage = cvCreateMemStorage(0);

	fInfo 						= new faceInfo[MAX_NUM_FACE_TO_FIND];

	nFaces = 0;

}


int* headmanager::detect(ofxCvColorImage imag){

	IplImage		*img;
	img = imag.getCvImage();
	cvCvtColor( img, gray, CV_BGR2GRAY );
	cvResize( gray, small_img, CV_INTER_LINEAR );
    cvClearMemStorage( storage );

    int holder[2];
    holder[0] = 0;
    holder[1] = 0;

    if( cascade )
    {
        double t = (double)cvGetTickCount();
		faces = cvHaarDetectObjects( small_img, cascade, storage,1.15, 4, CV_HAAR_DO_CANNY_PRUNING, cvSize(30,30) );
        t = (double)cvGetTickCount() - t;
		//printf( "detection time = %gms   %i\n", t/((double)cvGetTickFrequency()*1000.), faces->total);

		nFaces = faces ? faces->total : 0;
	int i;
	for( i = 0; i < nFaces; i++ )
        {
            CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
            float radius = cvRound((r->width + r->height)*0.25*scale);
			fInfo[i].radius = radius;
			fInfo[i].x = (r->x + r->width*0.5)*scale;
			fInfo[i].y = (r->y + r->height*0.5)*scale;
        }
        if(nFaces >0){
        holder[0]= fInfo[0].x;
        holder[1]= fInfo[0].y;
        }else{

    holder[0] = 0;
    holder[1] = 0;
        }
	}

    return(holder);
}


void headmanager::draw(int width, int height){
	for(int i = 0; i < nFaces; i++){
		ofSetColor(10,255,50);
		ofNoFill();

        ofSetLineWidth(6);
		ofCircle((float)width/camW * fInfo[i].x, (float)height/camH * fInfo[i].y, (float)height/camH *fInfo[i].radius);
	}
}
